import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Class to represent SeekingEye Enemy
 */
public class SeekingEye  extends Actor implements Runnable
{

    private Simon player;
    Health health;

    private float speed;
    private int playerX;
    private int playerY;
    private float rise;
    private float run; 
    private int skip;

    private int moveCounter;
    
    retroWorld theWorld;
    
    private volatile Thread t;
    private boolean alive;
    
    private GreenfootImage[] movingLeft ;
    private GreenfootImage[] movingRight;
    private GreenfootImage[] death;
    
    public SeekingEye()
    {
     speed = 1;
     playerX=0;
     playerY=0;
     rise=0;
     run=0; 
     skip=0;
     moveCounter = 0;
    
      
     alive=true;
     
     movingLeft = new GreenfootImage[2];
     movingRight = new GreenfootImage[2];
     death = new GreenfootImage[4];
        
        
        movingLeft[0] = new GreenfootImage("EyeLeft1.png");
        movingLeft[1] = new GreenfootImage("EyeLeft2.png");
        movingRight[0] = new GreenfootImage("EyeRight1.png");
        movingRight[1] = new GreenfootImage("EyeRight2.png");
        
        for (int i = 0; i < 4; i++)
            death[i] = new GreenfootImage("CVDeath" + (i + 1) + ".png");
    }
    
    public void run()
    {
        while(alive)
        {
            
            seek();
            if(alive)
            cycleImage();
            
            try {
                t.sleep(20);
            } catch (InterruptedException e) {}
        }
    }
    
    public void addedToWorld(World world)
    {
        theWorld = (retroWorld)world;
         player = theWorld.getSimon();
        health = theWorld.getHealth();
 
        t = new Thread(this);
        t.start();
    }
    
    /** Update Simon's current location
     * 
     */
    private void getPlayerLocation()
    {
        playerX=player.getX();
        playerY=player.getY();
    }
    
    /** Follow Simon
     * 
     */
    private void seek()
    {
        checkCollision();
        if(!alive)
        return;
        
        if(checkKeys())
        { 
           speed=2;
        
        }else{speed=1;}
        
        getPlayerLocation();
        int startX=getX();
        int startY=getY();
        //float distance=getDistance(startX,startY,playerX, playerY);
        // float middleDistance=distance/2;
        if ((Math.abs(getX()-playerX)<5) && (Math.abs(getY()-playerY)<5))
            return;
       
        rise=(playerY-startY);
        run=(playerX-startX);
        
        if(rise<0 && run<0)
        {
            rise*=-1;
            run*=-1;
            
        }
        else if(run<0 && rise>0)
        {
           run*=-1;
           rise*=-1;
            
        }
        
        int direction=0;
        
        if(startX>playerX)
            direction=-1;
        else
            direction=1;     
        
        float slope=0;
        if(run!=0)
            slope=rise/run;   
        
        //while((Math.abs(getX()-playerX)>5) || (Math.abs(getY()-playerY)>5) ){
        //if(getDistance(getX(),getY(),playerX, playerY)>middleDistance )
            //speed+=acceleration;
        //else
            //speed-=acceleration;      
            
        int newX=0;
        int newY=0;
          
            
        if(run!=0 && rise!=0)
        {
             
        // double angle=Math.atan(slope);
        /*for some reason the it does not like to take the 
        * x and y components for velocity >.<
        */
                
        newX=(int)(getX()+(direction*speed));
        newY=(int)(getY()+(direction*slope*speed));
        setLocation(newX,newY);
        }
        else if(run==0)
        {
            if(startY>playerY)//lower
                setLocation(getX(),(int)(getY()-(speed)));
            else
                setLocation(getX(),(int)(getY()+(speed)));
        }
        else
        {
            setLocation((int)(getX()+(speed*direction)),getY());
        }                 
        //}//end seek           
        //   speed=0;
        
    }
    
    public static float getDistance(int x1, int y1, int x2, int y2)
    {
        double x=(x1-x2);
        double y=(y1-y2);
        
        return (float)Math.sqrt(x*x+ y*y);       
    }
    
    /** Check which keys are pressed by the player
     * 
     */
    private boolean checkKeys()
    {
        //Move left
        if (Greenfoot.isKeyDown("a") )
        {
            return theWorld.canScrollWorld(-1);       
        }
        
        //move right
        if (Greenfoot.isKeyDown("d") )
        {
            return theWorld.canScrollWorld(1);         
        }
        
        else
            return false;
    }
    
    /** Check Collision detection for Simon's whipping
     * 
     */
    private synchronized void checkCollision()
    {
            
        if (intersects(player))
        {
            if (player.isCurrentlyWhipping())
                removeFromWorld();  
            else if (player.isCurrentlyWhipping() == false){
                health.takeDamage();
            }
        }

        //Actor s = getOneIntersectingObject(Simon.class);
        //return (s!=null);
    } 
    
    /** Cycle through Sprite images for the Seeking Eye
     * 
     */
    private void cycleImage()
    {
        if (getX() % 10 == 0)
        {
            if (getX() > player.getX())
                setImage(movingLeft[moveCounter % 2]);
            else
                setImage(movingRight[moveCounter % 2]);                
            moveCounter++;
        }
    }
    
    /** Remove SeekingEye object from the world
     * 
     */
    public void removeFromWorld()
    {
        try {
        
            setImage(death[0]);
            t.sleep(100);
            setImage(death[1]);
            t.sleep(100);
            setImage(death[2]);
            t.sleep(100);
            setImage(death[3]);
            t.sleep(100);
            
        } catch (InterruptedException e) {}
        
        t = null;
        alive=false;
        theWorld.removeObject(this);
    }
}
